﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.IO;

using YLPublicService.TransferModel;

namespace GifTools
{
    public class GifMaker
    {

        Process processor;
        public GifMaker(Process processor, string ttfPath)
        {
            this.processor = processor;
            initi(ttfPath);
        }

        private void initi(string ttfPath)
        {
            pfc = new System.Drawing.Text.PrivateFontCollection();
            pfc.AddFontFile(ttfPath);
        }
        static System.Drawing.Text.PrivateFontCollection pfc;
        /// <summary>
        /// 根据模板中的定义，以及传入的值，生成一系列的图片。
        /// 参数是 生成图片需要的文字  Name为key  eg  boyname  value 江先生
        /// </summary>
        /// <param name="values"></param>
        public void MakeImages(Dictionary<string, string> data, string saveDir)
        {
            //是文字，而且又有传入的，就生成
            var drawImages = processor.mImages.mImage.Where(
                img => img.mIsDraw.ToLower() == "true" && data.ContainsKey(img.mName));
            foreach (var imgProcessor in drawImages)
            {
                int width = Convert.ToInt32(imgProcessor.mWidth);
                int height = Convert.ToInt32(imgProcessor.mHeigth);
                int fontSize = Convert.ToInt32(imgProcessor.mFontSize);
                Color pen = imgProcessor.mColor.ToColor();
                Color backGroundPen = imgProcessor.mBackColor.ToColor();
                string text = data[imgProcessor.mName];
                FontStyle fs = imgProcessor.mIsBold.ToLower() == "true" ? FontStyle.Bold : FontStyle.Regular;
                string outPutPath = Common.conbindPath(saveDir, imgProcessor.mSaveName);
                make(width, height, fontSize, pen, backGroundPen, text, fs, outPutPath);
            }
        }
        /// <summary>
        /// 添加偏移左上角功能
        /// </summary>
        /// <param name="data"></param>
        /// <param name="saveDir"></param>
        /// <param name="offsetx"></param>
        /// <param name="offsety"></param>
        public void MakeImages(Dictionary<string, string> data, string saveDir, float offsetx, float offsety)
        {
            //是文字，而且又有传入的，就生成
            var drawImages = processor.mImages.mImage.Where(
                img => img.mIsDraw.ToLower() == "true" && data.ContainsKey(img.mName));
            foreach (var imgProcessor in drawImages)
            {
                int width = Convert.ToInt32(imgProcessor.mWidth);
                int height = Convert.ToInt32(imgProcessor.mHeigth);
                int fontSize = Convert.ToInt32(imgProcessor.mFontSize);
                Color pen = imgProcessor.mColor.ToColor();
                Color backGroundPen = imgProcessor.mBackColor.ToColor();
                string text = data[imgProcessor.mName];
                FontStyle fs = imgProcessor.mIsBold.ToLower() == "true" ? FontStyle.Bold : FontStyle.Regular;
                string outPutPath = Common.conbindPath(saveDir, imgProcessor.mSaveName);
                make(width, height, fontSize, pen, backGroundPen, text, fs, outPutPath, offsetx, offsety);
            }
        }
        private void make(int width, int height, int fontSize, Color pen, Color backGroundPen, string text, FontStyle fs, string outPutPath, float offsetx, float offsety)
        {
            Bitmap bitmap = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(bitmap);
            Brush penBrush = new SolidBrush(pen);
            g.Clear(backGroundPen);

            Font f = new Font(
                   pfc.Families[0],
                   fontSize,
                   fs
                );
            //设置文本输出质量
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;


            g.DrawString(text, f, penBrush, offsetx, offsety);

            g.Save();
            g.Dispose();
            bitmap.MakeTransparent(backGroundPen);
            bitmap.Save(outPutPath, ImageFormat.Png);
        }
        private void make(int width, int height, int fontSize, Color pen, Color backGroundPen, string text, FontStyle fs, string outPutPath)
        {
            Bitmap bitmap = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(bitmap);
            Brush penBrush = new SolidBrush(pen);
            g.Clear(backGroundPen);

            Font f = new Font(
                   pfc.Families[0],
                   fontSize,
                   fs
                );
            //设置文本输出质量
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;


            g.DrawString(text, f, penBrush, 0, 0);

            g.Save();
            g.Dispose();
            bitmap.MakeTransparent(backGroundPen);
            bitmap.Save(outPutPath, ImageFormat.Png);
        }
        public void MakeImage()
        {

        }
        #region 暂时不用
        void MakeName(string name, string outputPath)
        {
            Color pen = Color.White;
            Color bp = Color.FromArgb(254, 254, 254);
            make(130, 40, 30, pen, bp,
                name, FontStyle.Bold, outputPath);
        }
        void MakeTime(string time, string outputPath)
        {
            Color pen = Color.FromArgb(0xB4, 0x3A, 0x3c);
            make(310, 35, 25, pen, Color.White, time, FontStyle.Regular, outputPath);
        }
        void MakeAddr(string addr, string outputPath)
        {
            Color pen = Color.FromArgb(0xB4, 0x3A, 0x3C);
            make(380, 35, 25, pen, Color.White, addr, FontStyle.Regular, outputPath);
        }
        #endregion
        #region 旧代码
        //public static string PickedPaletteImagePath = Properties.Settings.Default.PickedPaletteImagePath;
        //public static void CreateImage(int width, int height, string text, Brush pen, int fontSize, string outputFileName, ImageFormat imageFormat)
        //{
        //    Bitmap orginal = Bitmap.FromFile(PickedPaletteImagePath) as Bitmap;

        //    Bitmap bm = new Bitmap(width, height, PixelFormat.Format32bppArgb);

        //    #region TTF loading
        //    string fontFamilly = TTFPath;
        //    var fc = new System.Drawing.Text.PrivateFontCollection();
        //    fc.AddFontFile(fontFamilly);
        //    Font f = new Font(
        //            fc.Families[0],
        //            fontSize
        //        );
        //    #endregion
        //    using (var g = Graphics.FromImage(bm))
        //    {
        //        g.DrawString(text, f, pen, 0, 0);
        //    }
        //    var newbm = CreateIndexedImage(bm, orginal.Palette);
        //    newbm.Save(outputFileName, imageFormat);
        //    bm.Dispose();
        //} 
        #endregion
        #region 过时
        ///// <summary>
        ///// 可以用了
        ///// </summary>
        //public static void CreateGIF(int width, int height, string text, Brush pen, int fontSize, string outputFileName)
        //{
        //    CreateImage(width, height, text, pen, fontSize, outputFileName, ImageFormat.Gif);
        //}
        //public static void CreatePNG(int width, int height, string text, Brush pen, int fontSize, string outputFileName)
        //{
        //    CreateImage(width, height, text, pen, fontSize, outputFileName, ImageFormat.Png);
        //}
        //public static void CreateTransparentPNG(int width, int height, int x, int y, string text, Brush pen, int fontSize, string outputFileName)
        //{
        //    Bitmap bitmap = new Bitmap(width, height);
        //    Graphics g = Graphics.FromImage(bitmap);
        //    // g.Clear(Color.Transparent);
        //    #region TTF loading
        //    string fontFamilly = TTFPath;
        //    var fc = new System.Drawing.Text.PrivateFontCollection();
        //    fc.AddFontFile(fontFamilly);
        //    Font f = new Font(
        //            fc.Families[0],
        //            20
        //        );
        //    #endregion
        //    g.DrawString(text, f, pen, x, y);
        //    g.Save();
        //    g.Dispose();
        //    bitmap.MakeTransparent(Color.Transparent);
        //    bitmap.Save(outputFileName, ImageFormat.Png);

        //}
        //public static void CreateTransparentGIF(int width, int height, int x, int y, string text, Brush pen,Font f, int fontSize, string outputFileName)
        //{
        //    Bitmap bitmap = new Bitmap(width, height);
        //    Graphics g = Graphics.FromImage(bitmap);
        //    // g.Clear(Color.Transparent);
        //    //#region TTF loading
        //    //string fontFamilly = TTFPath;
        //    //var fc = new System.Drawing.Text.PrivateFontCollection();
        //    //fc.AddFontFile(fontFamilly);
        //    //Font f = new Font(
        //    //        fc.Families[0],
        //    //        20, FontStyle.Bold, GraphicsUnit.Document
        //    //    );
        //    //#endregion
        //    g.DrawString(text, f, pen, x, y);
        //    g.Save();
        //    g.Dispose();
        //    bitmap.MakeTransparent(Color.Transparent);
        //    bitmap.Save(outputFileName, ImageFormat.Gif);

        //}
        //private static int Color2Int(Color color)
        //{
        //    return (color.R * 1000000 + color.G * 1000 + color.B);
        //}
        //private static int GetNearestColor(ColorPalette pal, Color c)
        //{
        //    int nearest = int.MaxValue;
        //    int index = 0;
        //    for (int i = 0; i < pal.Entries.Length; i++)
        //    {
        //        Color cc = pal.Entries[i];
        //        int distance = Convert.ToInt32(Math.Pow(cc.R - c.R, 2) + Math.Pow(cc.G - c.G, 2) + Math.Pow(cc.B - c.B, 2));

        //        if (distance < nearest)
        //        {
        //            index = i;
        //            nearest = distance;
        //        }
        //    }

        //    return index;
        //}
        //private static Bitmap CreateIndexedImage(Bitmap src, ColorPalette palette)
        //{
        //    //Create an indexed image.
        //    Bitmap dest = new Bitmap(src.Width, src.Height, PixelFormat.Format8bppIndexed);
        //    //Create a dictionary of colors to speed up the search.
        //    Dictionary<int, int> colors = new Dictionary<int, int>();
        //    //The transparent color index.
        //    int transparent = 255;
        //    //Load the dictionary with the given palette.
        //    for (int i = 0; i < palette.Entries.Length; i++)
        //    {
        //        colors[Color2Int(palette.Entries[i])] = i;
        //        if (palette.Entries[i].A == 0)
        //            transparent = i;
        //    }
        //    //Set the palette of the image.
        //    dest.Palette = palette;

        //    Rectangle rect = new Rectangle(0, 0, src.Width, src.Height);
        //    //Lock the image data so you can modify it.
        //    BitmapData destData = dest.LockBits(rect, ImageLockMode.ReadWrite, dest.PixelFormat);

        //    //The number of bytes in each line of the image.
        //    int dStride = Convert.ToInt32(Math.Abs(destData.Stride));
        //    //Create a buffer to hold the image data.
        //    byte[] destBytes = new byte[dest.Height * dStride];
        //    //Copy the image data into the buffer.
        //    IntPtr destPtr = destData.Scan0;
        //    Marshal.Copy(destPtr, destBytes, 0, dest.Height * dStride);
        //    //Select the best fit color index for each pixel in the image.
        //    for (int row = 0; row < src.Height; row++)
        //    {
        //        for (int col = 0; col < src.Width; col++)
        //        {
        //            //Get the color of the pixel.
        //            Color c = src.GetPixel(col, row);
        //            int index = 255;
        //            if (c.A == 0) //Transparent
        //            {
        //                index = transparent;
        //            }
        //            else
        //            {
        //                //Get the nearst color from the palette.
        //                int ic = Color2Int(c);
        //                if (colors.ContainsKey(ic))
        //                {
        //                    index = colors[ic];
        //                }
        //                else
        //                {
        //                    index = GetNearestColor(palette, c);
        //                    colors[ic] = index;
        //                }
        //            }
        //            //Update the color index in the buffer.
        //            destBytes[row * dStride + col] = (byte)index;
        //        }
        //    }
        //    //Copy the image data back to the image.
        //    Marshal.Copy(destBytes, 0, destPtr, dest.Height * dStride);
        //    //Unlock the data.
        //    dest.UnlockBits(destData);

        //    return dest;
        //}

        //public static void Make()
        //{

        //    Brush foreBrush = Brushes.Blue;
        //    Font font = new Font("幼圆", Convert.ToInt16(40), FontStyle.Regular);
        //    Graphics g = this.CreateGraphics();
        //    string text = "博客园";
        //    SizeF size = g.MeasureString(text, font);
        //    Single posX = (this.Width - Convert.ToInt16(size.Width)) / 2;
        //    Single posY = (this.Height - Convert.ToInt16(size.Height)) / 2;
        //    g.TranslateTransform(posX, posY);
        //    Matrix transform = g.Transform;

        //    //右倾斜文字
        //    //float shearX = -0.230F; 

        //    //左倾斜文字
        //    float shearX = 0.550F;
        //    float shearY = 0.10F;
        //    transform.Shear(shearX, shearY);
        //    g.Transform = transform;
        //    g.DrawString(text, font, foreBrush, 0, 0);
        //} 
        #endregion
    }
}